package ru.papergames.battleserver.model.battle;

import ru.papergames.Config;
import ru.papergames.battleserver.model.AbstractPaperGameUser;
import ru.papergames.battleserver.model.PaperGameFlashUser;
import ru.papergames.battleserver.model.battle.npc.processors.NpcActionProcessor;
import ru.papergames.battleserver.model.battle.statisticscalculators.BattlePlayerStatistics;
import ru.papergames.battleserver.network.serverpackets.flashuser.BattlePlayerActionPointsChanged;
import ru.papergames.battleserver.network.serverpackets.flashuser.PaperGameServerPacket;
import ru.papergames.common.form.PcPlayerForm;

/**
 * @author: atroshanin
 * Date: 10.04.2010
 * Time: 18:59:11
 */
public class BattlePlayer {

    private int teamId;
    private AbstractBattle battle;
    private AbstractPaperGameUser gameUser;
    private long gameUserId;
    private BallColor ballColor;
    private BattlePlayerStatistics statistics;

    private int actionPointsLeft;
    private long lastActionFinishTime;

    private boolean npcsCanNotActInBattle;
    private boolean battleLoaded;
    private int turnNumber;
    private boolean dead;
    private boolean connected;

    public BattlePlayer(AbstractBattle battle, AbstractPaperGameUser gameUser, int teamId) {
        this(battle, gameUser, teamId, BallColor.getBallColorById(teamId + 1));
    }

    public BattlePlayer(AbstractBattle battle, AbstractPaperGameUser gameUser, int teamId, BallColor ballColor) {
        this.battle = battle;
        this.gameUser = gameUser;
        this.gameUserId = gameUser.getId();
        this.teamId = teamId;
        this.ballColor = ballColor;
        this.statistics = new BattlePlayerStatistics();
    }

    public long getId() {
        return gameUserId;
    }

    public int getTeamId() {
        return teamId;
    }

    public AbstractBattle getBattle() {
        return battle;
    }

    public BallColor getBallColor() {
        return ballColor;
    }

    public void sendPacket(PaperGameServerPacket msg) {
        AbstractPaperGameUser playerTmp = gameUser;
        if (playerTmp != null) {
            playerTmp.sendPacket(msg);
        }
    }

    public AbstractPaperGameUser getGameUser() {
        return gameUser;
    }

    public void setGameUser(AbstractPaperGameUser gameUser) {
        this.gameUser = gameUser;
    }

    public BattlePlayerStatistics getStatistics() {
        return statistics;
    }

    public boolean isNpcsCanNotActInBattle() {
        return npcsCanNotActInBattle;
    }

    public boolean isNpcsActionsAllowed() {
        return !npcsCanNotActInBattle;
    }

    public void setNpcsCanNotActInBattle(boolean npcsCanNotActInBattle) {
        this.npcsCanNotActInBattle = npcsCanNotActInBattle;
    }

    public void allowNpcActions() {
        this.npcsCanNotActInBattle = false;
    }

    public void disallowNpcActions() {
        this.npcsCanNotActInBattle = true;
    }

    /**
     * here we determine whether client has connected to server.
     * @return true if client has connected
     */
    public boolean isConnected() {
        return gameUser != null && !gameUser.isDetached();
    }

    public void setConnected(boolean connected) {
        this.connected = connected;
    }

    /**
     * here we determine whether client has loaded battle map and battle members
     * @return true if client is ready for turn.
     */
    public boolean isBattleLoaded() {
        return battleLoaded;
    }

    public void setBattleLoaded(boolean battleLoaded) {
        this.battleLoaded = battleLoaded;
    }

    public int getTurnNumber() {
        return turnNumber;
    }

    public void setTurnNumber(int turnNumber) {
        this.turnNumber = turnNumber;
    }

    public boolean isDead() {
        return dead;
    }

    public void setDead() {
        this.dead = true;
    }

    public void setDead(boolean dead) {
        this.dead = dead;
    }

    public boolean isPcPlayer() {
        return gameUser instanceof PaperGameFlashUser;
    }

    public int getActionPointsLeft() {
        return actionPointsLeft;
    }

    public void setActionPointsLeft(int actionPointsLeft) {
        this.actionPointsLeft = actionPointsLeft;
    }

    public void decreaseActionPoints(int actPoints, BattlePlayerAction action) {
        //TODO: implement this logic
        actionPointsLeft = actionPointsLeft - actPoints;
        if (actPoints != 0) {
            sendPacket(new BattlePlayerActionPointsChanged(this));
        }
    }

    public boolean hasEnougthActionPoints(int actPoints, BattlePlayerAction action) {
        //TODO: implement this logic
        return actionPointsLeft >= actPoints;
    }

    public long getLastActionFinishTime() {
        return lastActionFinishTime;
    }

    public void setLastActionFinishTime(long lastActionFinishTime) {
        this.lastActionFinishTime = lastActionFinishTime;
    }

    public boolean isLastActionStillProceeds() {
        return System.currentTimeMillis() < lastActionFinishTime;
    }

    public void recalculateActionPoints() {
        actionPointsLeft = Config.AP_PER_TURN;
    }

    public NpcActionProcessor getActionProcessor() {
        return gameUser.getActionProcessor();
    }
}
